package com.fwtai.security;

import com.fwtai.bean.JwtUser;
import com.fwtai.bean.SysUser;
import com.fwtai.exception.ErrorException;
import com.fwtai.exception.HandlerException;
import com.fwtai.service.AsyncHandler;
import com.fwtai.service.AsyncService;
import com.fwtai.service.core.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

@Service
public class UserDetailsServiceImpl implements UserDetailsService {

  @Autowired
  private UserService userService;

  @Resource
  private AsyncService asyncService;

  @Resource
  private ThreadPoolTaskExecutor taskExecutor;

  @Override
  public UserDetails loadUserByUsername(final String username) throws UsernameNotFoundException {
    return new AsyncHandler<JwtUser>().asyncCompute(()->{
      final SysUser user = userService.getUserByUserName(username);
      if(user == null) throw new UsernameNotFoundException("账号或密码有误");//它会走认证失败的回调,即方法 unsuccessfulAuthentication()
      final Integer enabled = user.getEnabled();
      if(enabled == 0){
        asyncService.updateLogin(username);
      }
      return new JwtUser(user.getKid(),user.getUserName(),user.getPassword(),enabled);
    }).join();
  }

  /**
   * 通过userId`动态`获取用户的全部角色和权限的信息,适用于PC端
   * @param
   * @作者 田应平
   * @QQ 444141300
   * @创建时间 2020/5/1 0:49
  */
  public JwtUser getUserById(final String userId,final String url){
    return new AsyncHandler<JwtUser>().asyncCompute(()->{
      final List<String> roles = userService.getRolePermissions(userId,url);
      if(roles.size() <= 0){
        throw new HandlerException("没有操作权限");
      }
      final List<SimpleGrantedAuthority> authorities = new ArrayList<>(roles.size());
      for(final String role : roles){
        if(role != null){
          authorities.add(new SimpleGrantedAuthority(role));
        }
      }
      return new JwtUser(userId,authorities);
    }).join();
  }

  //移动端无需动态鉴权,但需要登录,若token是无效的则不会执行到此,适用于移动端小程序端
  public JwtUser getUserInfo(final String userId){
    final SysUser sysUser = CompletableFuture.supplyAsync(() -> userService.getUserById(userId),taskExecutor).join();
    if(sysUser != null){
      return new JwtUser(sysUser.getUserName(),new ArrayList<>(0));
    }
    throw new ErrorException("系统已更新请重新登录");
  }
}